# TODO Tushare::Stock::Trading.get_realtime_quotes   看看Tushare gem 里还有哪些方法可用
require 'open-uri'
namespace :ths do
  # rake ths:choice_block["N"]
  # rake ths:choice_block["I"]
  # 概念板块 5、10、20 天 top10 交集
  desc "choice_block"
  task :choice_block, [:type] => :environment do |t, args|
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "【init:block['#{args[:type]}']}】start_time: #{Time.now}"
    end
    arr = args[:type] == "N" ? gnzj : hyzjl

    top5 arr
    top_n arr, 20
    puts "###############################################################################"
    days, count = 16, 10
    $TusharePro.tushare_pro("index_daily", ts_code: "000001.SH", "start_date": trade_date(days), "end_date": Time.now.strftime("%Y%m%d")).each do |index_daily|
      File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
        f.puts "=======================#{index_daily["trade_date"]} 日   #{index_daily["pct_chg"]}======================="
      end
      puts "=======================#{index_daily["trade_date"]} 日   #{index_daily["pct_chg"]}======================="
      ths_dailies = $TusharePro.tushare_pro("ths_daily", trade_date: index_daily["trade_date"]).select { |x| x["ts_code"][0] == "8" && ["5", "6"].include?(x["ts_code"][2]) }.sort_by { |x| x["pct_change"] }
      (ths_dailies.last(count).reverse + ths_dailies.first(count).reverse).each_with_index do |ths_daily, index|
        puts "-----------------------------------" if index == count
        block = Block.find_by_ts_code(ths_daily["ts_code"])
        File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
          f.puts "#{ths_daily["ts_code"][0..5]} -- #{block.name} -- #{block.cate_type} -- #{ths_daily["pct_change"]}" unless block.nil?
        end
        puts "#{ths_daily["ts_code"][0..5]} -- #{block.name} -- #{block.cate_type} -- #{ths_daily["pct_change"]}" unless block.nil?
      end
    end
    puts "###############################################################################"
    # TODO 把龙头记录到数据库
    # limit_list days 天内涨停板天梯
    limit_list 20
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "【init:block['#{args[:type]}']】end_time: #{Time.now}"
    end
  end

  # 板块个股看板 rake ths:block_stock['885462.TI','10']  参数： 板块编号，分析最近 n 天
  desc "block_stock"
  task :block_stock, [:ts_code, :n] => :environment do |t, args|
    ts_code = args[:ts_code] # 板块编号
    days = (args[:n] || 10).to_i # 板块分析最近 days 天
    trade_time20 = trade_date(20)
    stocks = $TusharePro.tushare_pro("ths_member", "ts_code": ts_code).select { |x| x["con_code"][0..5] < "680000" && x["con_code"][0] != "4" }
    # 先找到板块的龙头
    $TusharePro.tushare_pro("ths_daily", ts_code: ts_code)[0..days].reverse.each do |daily|
      puts "----------#{Block.find_by_ts_code(ts_code).name}板块--#{daily["trade_date"]}日--涨幅：#{daily["pct_change"]}，强于板块涨幅的个股：------"
      dailies = $TusharePro.tushare_pro("daily", "trade_date": daily["trade_date"]).select { |daily| stocks.pluck("con_code").include? daily["ts_code"] }
      Parallel.map(dailies, in_processes: 1) do |st|
        if daily["pct_change"].to_f < st["pct_chg"].to_f && st["pct_chg"].to_f > 3
          year_count = Stock.find_by_ts_code(st["ts_code"])&.year_count
          puts "#{st["ts_code"][0..5]}  #{stocks.find { |hash| hash["con_code"] == st["ts_code"] }["con_name"]}  , 涨幅：#{st["pct_chg"]}, 涨停次数：#{year_count}"
        end
      end
    end
    # 个股分析

    arr = []
    stocks.each do |st|
      delay_millisecond(1, rand(50..100)) {}
      view = {}
      limit_count = $TusharePro.tushare_pro("limit_list_d", "ts_code": st["con_code"], "limit_type": "U", "start_date": (Time.now - 365.day).strftime("%Y%m%d"), "end_date": Time.now.strftime("%Y%m%d")).count
      # next if limit_count < 1
      stock_moneyflow = $TusharePro.tushare_pro("moneyflow", ts_code: st["con_code"], "start_date": trade_time20, "end_date": Time.now.strftime("%Y%m%d"))
      (puts "无法获取 #{st["con_code"]} stock_moneyflow"; next) if stock_moneyflow.blank?
      daily_basic = $TusharePro.tushare_pro("daily_basic", ts_code: st["con_code"]).first

      realtime_stock_info = Tushare::Stock::Trading.get_k_data st["con_code"][0..5]
      next if realtime_stock_info.blank?
      today = realtime_stock_info[-1]
      yesterday = realtime_stock_info[-2]
      change = ((today["close"].to_f - yesterday["close"].to_f) * 100 / yesterday["close"].to_f).round(2)

      ths_flow = RealTime.ths_flow st["con_code"][0..5]
      view["con_code"] = st["con_code"][0..5]
      view["pe"] = daily_basic["pe"]&.round(0)
      view["total_mv"] = (daily_basic["total_mv"] / 10000).round(0)
      view["trade_date"] = stock_moneyflow[0]["trade_date"][4..7]
      view["net_mf_amount"] = stock_moneyflow[0]["net_mf_amount"]
      view["change"] = change
      view["limit_count"] = limit_count
      view["score"] = ths_flow["score"]
      view["con_name"] = st["con_name"]
      view["je"] = ths_flow["title"]["je"]
      view["today_volume"] = today_volume st["con_code"]
      arr << view
      print_stock view
    end
    puts "-----------------------sort_by: limit_list_d--------------------------------------"
    arr.sort_by { |x| x["limit_count"] }.reverse.each do |view|
      print_stock view
    end
    puts "-----------------------sort_by: net_mf_amount-------------------------------------"
    arr.sort_by { |x| x["je"].to_i }.reverse.each do |view|
      print_stock view
    end
    puts "-----------------------sort_by: change-------------------------------------"
    arr.sort_by { |x| x["change"] }.reverse.each do |view|
      print_stock view
    end
    puts "-----------------------filter:  je>0 score>4.5 pe>0  sort_by: change-------------------------------------"
    arr.select { |x| x["je"].to_f > 0 }
       .select { |x| x["score"].to_f > 4.5 }
       .select { |x| x["pe"].to_f > 0 }
       .sort_by { |x| x["change"] }.reverse.each do |view|
      print_stock view
    end
    puts Time.now.to_s
  end

  # 异动解读 英文fluctuation
  # 信息来源：https://t.10jqka.com.cn/686873744/?posttype=post【花解异动】
  # rake ths:fluctuation
  desc "fluctuation"
  task :fluctuation => :environment do
    Nokogiri::HTML(URI.open("https://t.10jqka.com.cn/686873744/?posttype=post")).css('.hpage-ucwlist li').each do |li|
      title = li.css('a').text.split("\n").first.split('阅读').first&.strip
      next if title.blank?
      href = li.css('a').attr('href').value
      puts name = title.split("】").last.split("#{Time.now.month}月").first.strip
      stock = Stock.find_by_name(name)
      next if stock.nil?
      Fluctuation.find_or_create_by(title: title, href: href) do |fluctuation|
          fluctuation.title = title
          fluctuation.href = href
          fluctuation.name = name
          fluctuation.code = stock.symbol
          # 大涨、大跌、涨停、跌停
          fluctuation.trend = title.include?("涨停") ? "涨停" : (title.include?("大涨") ? "大涨" : (title.include?("跌停") ? "跌停" : (title.include?("大跌") ? "大跌" : "other")))

      end
    end
  end
end

def puts_limit_list_d limit_list_d
  File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
    f.puts "#{limit_list_d["trade_date"]}  #{limit_list_d["ts_code"][0..5]}   #{limit_list_d["name"]}   #{limit_list_d["industry"]} 连板数量:#{limit_list_d["limit_times"]}"
  end
  puts "#{limit_list_d["trade_date"]}  #{limit_list_d["ts_code"][0..5]}   #{limit_list_d["name"]}   #{limit_list_d["industry"]} 连板数量:#{limit_list_d["limit_times"]}"
end

def print_stock(view)
  printf("%6s 市盈率：%3s 总市值：%5s %4s净流入：%10s 涨幅：%5s%% 1年涨停：%2s次 score: %3s 量比：%4s 当前流入：%10s %4s \n",
         view["con_code"], view["pe"], view["total_mv"], view["trade_date"], view["net_mf_amount"],
         view["change"], view["limit_count"], view["score"], view["today_volume"], view["je"], view["con_name"])
end

# gnzjl 概念资金流
# https://data.10jqka.com.cn/funds/gnzjl

def gnzj
  gnzj = []
  gnzj << nok_block_flow('/funds/gnzjl/')
  gnzj << nok_block_flow('/funds/gnzjl/board/3/ajax/1/')
  gnzj << nok_block_flow('/funds/gnzjl/board/5/ajax/1/')
  gnzj << nok_block_flow('/funds/gnzjl/board/10/ajax/1/')
  gnzj << nok_block_flow('/funds/gnzjl/board/20/ajax/1/')
end

def hyzjl
  hyzjl = []
  hyzjl << nok_block_flow('/funds/hyzjl/')
  hyzjl << nok_block_flow('/funds/hyzjl/board/3/ajax/1/free/1/')
  hyzjl << nok_block_flow('/funds/hyzjl/board/5/ajax/1/free/1/')
  hyzjl << nok_block_flow('/funds/hyzjl/board/10/ajax/1/free/1/')
  hyzjl << nok_block_flow('/funds/hyzjl/board/20/ajax/1/free/1/')
end

# doc = Nokogiri::HTML(URI.open("https://data.10jqka.com.cn/funds/gnzjl/"))
# doc = Nokogiri::HTML(URI.open("https://data.10jqka.com.cn/funds/hyzjl/"))
def nok_home type
  doc = Nokogiri::HTML(URI.open("https://data.10jqka.com.cn/funds/#{type}/"))
  # doc = Nokogiri::HTML(URI.open("https://q.10jqka.com.cn/"))
  # doc = Nokogiri::HTML(URI.open("https://stock.10jqka.com.cn/fupan/"))
  # doc = Nokogiri::HTML(URI.open("https://yuanchuang.10jqka.com.cn/zhangting/"))
  # doc = Nokogiri::HTML(URI.open("https://data.10jqka.com.cn/funds/gnzjl/field/tradezdf/order/desc/page/2/ajax/1/free/1/"))
  arr = []
  doc.css('tbody').css('tr').each do |board|
    ob = {}
    ob["id"] = board.css('td')[0].text
    ob["name"] = board.css('td')[1].text
    ob["index"] = board.css('td')[2].text
    ob["change"] = board.css('td')[3].text
    ob["in"] = board.css('td')[4].text
    ob["out"] = board.css('td')[5].text
    ob["net_amount"] = board.css('td')[6].text
    ob["count"] = board.css('td')[7].text
    arr << ob
  end
  arr
end

def nok_block_flow path
  puts path
  arr = []
  doc = Nokogiri::HTML(ths.get(path).body)
  doc.css('tbody').css('tr').each do |board|
    ob = {}
    ob["id"] = board.css('td')[0].text
    ob["name"] = board.css('td')[1].text
    ob["index"] = board.css('td')[2].text
    ob["change"] = board.css('td')[3].text
    ob["in"] = board.css('td')[4].text
    ob["out"] = board.css('td')[5].text
    ob["net_amount"] = board.css('td')[6].text
    ob["count"] = board.css('td')[7].text
    ob["days"] = path.split("/")[4]
    arr << ob
  end
  if arr.blank?
    puts 'https://data.10jqka.com.cn' + path
    debugger
  end
  arr
end

# 最强板块
def top5 gnzj_arr
  gnzj_arr.each do |gns|
    puts "--------------------------------------------------------------------"
    gns[0..4].each do |gn|
      File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
        f.puts "#{gn["days"].nil? ? "今" : gn["days"]}日前5：#{gn["name"]} -- rake ths:block_stock['#{Block.find_by_name(gn["name"])&.ts_code}']"
      end
      puts "#{gn["days"].nil? ? "今" : gn["days"]}日前5：#{gn["name"]} -- rake ths:block_stock['#{Block.find_by_name(gn["name"])&.ts_code}']"
    end
  end
end

def top_n gnzj_arr, n
  gn_arr = gnzj_arr.map { |x| x.take(n) }
  puts "--------------------------------------------------------------------"
  arr1 = gn_arr[0].pluck("name") & gn_arr[1].pluck("name") & gn_arr[2].pluck("name") & gn_arr[3].pluck("name") & gn_arr[4].pluck("name")
  arr1.each do |arr|
    next if Block.find_by_name(arr).nil?
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "今&3&5&10&20  前20：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
    end
    puts "今&3&5&10&20  前20：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
  end
  puts "--------------------------------------------------------------------"
  arr2 = gn_arr[0].pluck("name") & gn_arr[1].pluck("name") & gn_arr[2].pluck("name") & gn_arr[3].pluck("name")
  arr2.each do |arr|
    next if Block.find_by_name(arr).nil?
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "今&3&5&10     前20：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
    end
    puts "今&3&5&10     前20：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
  end
  puts "--------------------------------------------------------------------"
  arr3 = gn_arr[0].pluck("name") & gn_arr[1].pluck("name") & gn_arr[2].pluck("name")
  arr3.each do |arr|
    next if Block.find_by_name(arr).nil?
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "今&3&5        前20：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
    end
    puts "今&3&5        前20：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
  end
  puts "--------------------------------------------------------------------"
  arr4 = gn_arr[0].pluck("name") & gn_arr[1].pluck("name")
  arr4.each do |arr|
    next if Block.find_by_name(arr).nil?
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "今&3           前20：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
    end
    puts "今&3           前20：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
  end

  puts "--------  [今&3日] - [今3&5&10]日 - [今3&5&10&20]日 前20新出现  --------"
  (arr4 - arr2 - arr1).each do |arr|
    next if Block.find_by_name(arr).nil?
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "3日  前20新出现：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
    end
    puts "3日  前20新出现：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
  end

  puts "--------  [今&3日] - [今&3&5]日 - [今3&5&10]日 - [今3&5&10&20]日 前20新出现  --------"
  (arr4 - arr3 - arr2 - arr1).each do |arr|
    next if Block.find_by_name(arr).nil?
    Block.find_by_name(arr).update_attribute "is_choice", true
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "3日  前20新出现：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
    end
    puts "3日  前20新出现：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr).ts_code}']"
  end
  puts "-------------------------- 今日 前20新出现 --------------------------"
  arr5 = gn_arr[0].pluck("name")
  (arr5 - arr4 - arr3 - arr2 - arr1).each do |arr|
    next if Block.find_by_name(arr).nil?
    File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
      f.puts "今日  前20新出现：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr)&.ts_code}']"
    end
    puts "今日  前20新出现：#{arr} -- rake ths:block_stock['#{Block.find_by_name(arr)&.ts_code}']"
  end
  File.open "ths:choice_block_#{Time.now.strftime("%Y%m%d")}.txt", "a" do |f|
    f.puts "今           #{arr5}"
    f.puts "今&3         #{arr4}"
    f.puts "今&3&5       #{arr3}"
    f.puts "今&3&5&10    #{arr2}"
    f.puts "今&3&5&10&20 #{arr1}"
  end
  puts "今           #{arr5}"
  puts "今&3         #{arr4}"
  puts "今&3&5       #{arr3}"
  puts "今&3&5&10    #{arr2}"
  puts "今&3&5&10&20 #{arr1}"
end

def limit_list days
  puts "------------------------------按板块--------------------------------"
  start_date = Time.now.hour < 16 ? trade_date(days + 1) : trade_date(days)
  today = Time.now.hour < 16 ? trade_date(2) : trade_date(1)
  limit_list_ds = limit_list_d start_date
  limit_list_ds.select { |x| x["trade_date"] == today }.sort_by { |x| x["industry"] }.each { |limit_list_d| puts_limit_list_d limit_list_d }
  puts "-----------------------------按连板数量------------------------------"
  limit_list_ds.select { |x| x["trade_date"] == today }.sort_by { |x| x["limit_times"] }.each { |limit_list_d| puts_limit_list_d limit_list_d }
  puts "----------------------------20天内连板大于3--------------------------"
  limit_list_ds.sort_by { |x| x["limit_times"] }.select { |x| x["limit_times"] > 3 }.each { |limit_list_d| puts_limit_list_d limit_list_d }
end

def ths
  conn = Faraday.new(url: 'https://data.10jqka.com.cn',
                     headers: { "Cookie" => ENV['THS_COOKIE'] })
  conn
end

